#include <stdio.h>
#ifndef bool
#define bool int
#endif

#ifndef true
#define true 1
#endif

#ifndef false
#define false 0
#endif


#ifndef INT
#define INT 0
#endif

#ifndef CHAR
#define CHAR 1
#endif

#ifndef DOUBLE
#define DOUBLE 2
#endif

#define INDEX_NODE 1
#define DATA_NODE 3


typedef struct{
	char table_name[20];
	char table_key[20];
}ForeignKeyStruct;

typedef struct key{
	char name[20];
	int flag;
    /*
    primary Key     0000 0001
    auto_increment  0000 0010
    not null        0000 0100
    unique          0000 1000
    foreign         0001 0000
    */
	int restrain;
	int strlength;
    ForeignKeyStruct foreign_key; 
}KeyStruct;

#define KEY_INT 0
#define KEY_DOUBLE 1
#define KEY_CHAR 2

typedef struct FileHeader{
    int headerLength;
    int keyNumber;
    int m; 
    int blockSize;   
    int indexSize;
    int recordSize;
    int startBlock;
    int firstAvailableBlock;
    int lastAvailableBlock;
    int startDataBlock;
    int endDataBlock;
    int allockedBlockNumber;
}FileHeaderStruct,*FileHeaderStructPoint;

typedef struct BlockHeader{
    int pos;
    /*
        0 : free block ? 不一定满足
        不一定 free block的判断方式只能从firstAvailableBlock中顺序遍历
        1 : index block starter 一定满足
        2 : index block others ？不一定满足
        3 : data block starter 一定满足
        4 : data block others ？ 不一定满足
    */
    int type;
    // In Node,the data is store by order.We need the number. 
    int number;
    int blockNumber;
    int parentNode;
    /*
    Two direction Link in data block;
    */
    int nodeNext;
    int nodePrefix;
    /*
    The next block in this node;
    */
    int blockNext;
}BlockHeaderStruct,*BlockHeaderStructPoint;


typedef struct BlockHeaderLink{
    BlockHeaderStructPoint m_blockHeader;
    struct BlockHeaderLink * next;
}*BlockHeaderLinkPoint;


typedef struct BPNode{
    int type;
    int number;
    BlockHeaderLinkPoint m_blockHeaderLink;
    void * m_dataP;
}BPNodeStruct,* BPNodeStructPoint;


bool deleteDataByIndex(FILE * fp,FileHeaderStructPoint fhsp,BPNodeStructPoint bpNode,int index);

BPNodeStructPoint getAFreeBPNode(FILE * fp,FileHeaderStructPoint fhsp,int blockNumber);

int insertData(FILE * fp,int index,void * data,bool isAutoIncrement);

void writeBackBPNode(FILE * fp,FileHeaderStructPoint fhsp,BPNodeStructPoint bpNode);

void initBPFile(FILE * fp,int keyNumber,KeyStruct keyArray[]);

int getFileHeaderLength(int keyNumber);

BPNodeStructPoint searchNodeByIndex(FILE * fp,FileHeaderStructPoint fhsp,int index,BPNodeStructPoint bpNode);

BPNodeStructPoint segetNodeByIndex(FILE * fp,FileHeaderStructPoint fhsp,int index,BPNodeStructPoint bpNode);

BPNodeStructPoint getBPNodeByNumber(FILE * fp,FileHeaderStructPoint fhsp,int number);

int insertToIndexNode(FILE * fp,FileHeaderStructPoint fhsp,int ,void * data,BPNodeStructPoint bpNode);

void writeBackFileHeader(FILE * fp,FileHeaderStructPoint fhsp);

void writeBackBPNode(FILE * fp,FileHeaderStructPoint fhsp,BPNodeStructPoint bpNode);

void printBPtree(FILE * fp,FileHeaderStructPoint fhsp,int * stack,int start,int end,int size);